package com.kxf.checkapksoplugin.util

import com.kxf.checkapksoplugin.bean.ExecuteResult
import org.gradle.internal.impldep.org.apache.commons.lang.StringUtils
import org.gradle.tooling.*
import java.io.File
import java.util.concurrent.CountDownLatch

object ProjectConnUtils {

    /**
     * 执行任务
     *
     * @param rootProjectDir 根项目所在目录。
     * @param subProjectName 子工程名称，如果子项目名称为空,则表示在整个工程中执行任务
     * @param tasks 任务
     * @return 执行结果
     */
    fun execute(
        rootProjectDir: String?,
        subProjectName: String?,
        tasks: Array<String>
    ): ExecuteResult? {
        require(!StringUtils.isBlank(rootProjectDir)) { "根项目所在的目录不能为空!" }
        val root = File(rootProjectDir)
        require(root.exists()) { "根项目所在的目录不存在!" }
        requireNotNull(tasks) { "没有可执行的任务!" }
        val arguments = arrayOf("-xTest")
        if (StringUtils.isNotBlank(subProjectName)) {
            val sub: String = ":$subProjectName"
            if (StringUtils.isNotBlank(sub)) {
                for (i in tasks.indices) {
                    tasks[i] = sub + ":" + tasks[i]
                }
            }
        }
        return try {
            execute(root, tasks, arguments, arrayOf());
        } catch (e: Exception) {
            e.printStackTrace()
            ExecuteResult("-1", e)
        }
    }

    /**
     * 执行Gradle命令
     *
     * @param projectDir 项目目录
     * @param arguments 执行参数
     * @param jvmDefines jvm参数
     * @param tasks 任务
     * @return 执行结果
     */
    fun execute(
        projectDir: File,
        tasks: Array<String>,
        arguments: Array<String>,
        jvmArgs: Array<String>
    ): ExecuteResult? {
        val connection: ProjectConnection =
            GradleConnector.newConnector().forProjectDirectory(projectDir).connect()
        println("execute connection==>>$connection")
        val latch = CountDownLatch(1)
        val ret = ExecuteResult()
        try {
            val build =
                connection.newBuild().forTasks(*tasks).withArguments(*arguments)
            build.setStandardOutput(System.out)
            build.setJvmArguments(*jvmArgs)
            build.addProgressListener(object : ProgressListener {
                override fun statusChanged(event: ProgressEvent) {
                    println("execute gradle task status changed:" + event.getDescription())
                }
            })
            println("execute build.run==>>${build}")
            build.run(object : ResultHandler<Void?> {
                override fun onComplete(result: Void?) {
                    println("执行Gradle命令 onComplete==>>$result")
                    ret.resultCode = "1"
                    latch.countDown()
                }

                override fun onFailure(exception: GradleConnectionException?) {
                    println("执行Gradle命令 onFailure==>>$exception")
                    ret.resultCode = "-1"
                    ret.exception = exception
                    latch.countDown()
                }
            })
            latch.await()
        } catch (e: Exception) {
            println("执行Gradle命令出错:$e")
        } finally {
            connection.close()
        }
        return ret
    }
}